#include "SampleUI.h"
//目前支持的非显示字符只有'\n'

#define GET_STR_MAX_WIDTH(SCREEN_WIDTH,FNOT_WIDTH) (SCREEN_WIDTH/FNOT_WIDTH*FNOT_WIDTH)
#define IS_DISP_ASCII(x) (((x) >= ' ') && ((x) <= '~'))

struct SampleUIPage
{
    char *terminal_buf; //terminal页面文字的输入缓冲区
    uint8_t auto_roll; //自动滚屏标志位
    uint8_t char_size;  //文字页面字符大小
    uint16_t str_len; //terminal页面文字缓冲区中str的长度
    uint16_t buff_size; //terminal页面文字缓冲区的大小
    int16_t top_y; //页面顶端值
    int16_t end_x; //最后的x的位置
    window w_all; //画面限制
} terminal; //全集sampleui变量，只是用于oled模拟终端打印



static void SampledUI_Show(void)
{
    char * temp_buff = terminal.terminal_buf; //取出buff
    int16_t x = 0,y = 0, line_max_width = 0; //写字符的坐标
    uint8_t ending_flag = 2;//遍历结束标志位，用于标志第一次遍历结束，取出top_y该有的值
    uint8_t fnot_width = 0;
    y = (int16_t)(terminal.top_y);
    if(terminal.char_size == 8) fnot_width = 6; //8号字符宽度为6
    else fnot_width = (terminal.char_size>>1); //<=>/2 
    line_max_width = GET_STR_MAX_WIDTH(OLED_WIDTH,fnot_width);
    while(ending_flag)
    {
        if(x >= line_max_width || *temp_buff == '\n')
        {
            x=0;
            y += terminal.char_size; //字符大小共有三种，8，16，24，正好和高度相同
        }
        if(y>=OLED_HEIGHT)
        { //到达最后一行
            if(terminal.auto_roll)
            {
                if(terminal.top_y == 0)//第一次到最后一行
                    terminal.top_y = OLED_HEIGHT - (y + terminal.char_size);
                else 
                    terminal.top_y -= terminal.char_size; //往上直接移一个字符高度就可以
            }
        }
        if(*temp_buff == '\0')
        { 
            ending_flag--;
            if(ending_flag == 1)
            {
                temp_buff = terminal.terminal_buf; //重置buff指针
                y = (int16_t)(terminal.top_y);
                x = 0; //遍历第一次只为得到top_y的值，后面直接跳过
            }
            if(ending_flag == 0)terminal.end_x = (x+fnot_width); //最后一次退出时，记录下结束时x的值
        } 
        if(IS_DISP_ASCII(*temp_buff))
        {
            if(ending_flag == 1) //ending == 1开始打印
                OLED_WinDrawASCII(&terminal.w_all,x,y,terminal.char_size,*temp_buff);
            x += fnot_width; //只有是可显示的字符才会占一个位
        }
        temp_buff++;
    }
}

void SampleUI_Clear(void)
{
    terminal.str_len = 0;
    terminal.terminal_buf[0] = '\0';
    terminal.top_y = 0;
    terminal.end_x = 0;
}


void SampleUI_Init(char *terminal_buf, uint16_t buff_size,uint8_t char_size)
{
    terminal.auto_roll = 1; //默认滚动
    terminal.terminal_buf = terminal_buf; //文字缓冲区
    terminal.buff_size = buff_size; //缓冲区大小
    terminal.char_size = char_size; //字符大小
    terminal.top_y = 0; //起始默认0
    terminal.end_x = 0;
    terminal.str_len = 0; //没有字符输入(strlen变量只记录了buff内的字串长度，不含\0)
    terminal.w_all.start_x = 0;
    terminal.w_all.start_y = 0;
    terminal.w_all.h = OLED_HEIGHT;
    terminal.w_all.w = OLED_WIDTH; //限制窗口为页面大小
}

void SampleUI_Log(char *str)
{
    uint16_t str_len = strlen(str);
    if((str_len + terminal.str_len) > (terminal.buff_size - 1) ) //buff会留下最后一个\0
        SampleUI_Clear(); //如果打印超过了缓冲区的话，就清空缓冲区，重新开始
    memcpy(terminal.terminal_buf + terminal.str_len, str, str_len); //将新串追加到末尾
    terminal.str_len += str_len; //更新长度 
    terminal.terminal_buf[terminal.str_len] = '\0'; //添加结束符
    OLED_ClearBuff(); //清空oled缓冲区方便重新绘制
    SampledUI_Show();
    OLED_RefreshBuff(); //立即刷新打印数据
}

void SampleUI_Print(char *fmt,...)
{
    char fmt_str[128]; //用于格式化，单次打印字串<128
    va_list arg_ptr;
    va_start(arg_ptr, fmt);
    vsprintf(fmt_str, fmt, arg_ptr);
    va_end(arg_ptr);
    SampleUI_Log(fmt_str);
}

void SampleUI_BackSpace(uint8_t num)
{
    int16_t line_max_width = 0; //每行的最大宽度
    uint8_t fnot_width = 0;
    if(terminal.char_size == 8) fnot_width = 6; //8号字符宽度为6
    else fnot_width = (terminal.char_size>>1); //<=>/2 
    line_max_width = GET_STR_MAX_WIDTH(OLED_WIDTH,fnot_width);
    for (uint8_t i = 0; i < num; i++)
    {
        if(terminal.str_len == 0)break;
        else 
        {
            if(terminal.terminal_buf[terminal.str_len] == '\n')
                terminal.top_y += terminal.char_size;
            else 
            {
                terminal.end_x -= fnot_width;
                if(terminal.end_x <= 0)
                {
                    terminal.end_x = line_max_width;
                    terminal.top_y += terminal.char_size;
                }
            }
        }
        terminal.str_len--;
    }
    terminal.terminal_buf[terminal.str_len] = '\0'; //添加结束符
}
